/**
  ******************************************************************************
  * @file           : communicate_task.h
  * @author         : Tessia
  * @brief          : None
  * @attention      : None
  * @date           : 2024/2/15
  ******************************************************************************
  */



#ifndef SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H
#define SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H

#include "cmsis_os.h"
#include "usart.h"
#include "CAN_bsp.h"
#include "drv_can_dr16.h"
#include "yaw_task.h"
#include "driver_communicate.h"
#include "super_capacitor_drv.h"

#define UART_TX_SIGNAL      ( 1 << 2 )
#define UART_IDLE_SIGNAL    ( 1 << 1 )
#define DN_REG_ID    0xA5  //裁判系统通信

enum robot_num{
    hero = 1,
    engineer = 2,
    infantry_3 = 3,
    infantry_4 = 4,
    infantry_5 = 5,
    sentry = 7,
    base = 10,          //基地
    outpost = 11,       //前哨站
};

enum sentry_state{
    standby = 0,                      //待命状态
    attack,                           //进攻状态，该状态需视野中出现敌人
    high_priority_pathfinding,        //高优先级寻路状态，此时寻路不会被打断，不会反击
    mid_priority_pathfinding,         //中优先级寻路状态，此时寻路不会被打断，会反击
    low_priority_pathfinding,         //低优先级寻路状态，此时寻路会被打断

    patrol,                           //巡逻状态，固定几个点的巡逻状态
    stationary_defense,               //原地不动防守状态
    constrained_defense,              //约束防守状态，适用于第一次死亡前，前哨站被击毁后
    error,                            //错误状态，即进入了不该进入的状态转移表
    logic,                            //逻辑状态，在这里面做逻辑处理和强制状态转换

    pursuit,                          //追击状态，此时追击坐标为敌人消失的坐标
    free_defense,                     //自由防守状态，适用于第一次死亡后
    supply,                           //补给状态，弹丸打完或血量低下会进入此状态，attack、patrol、free_defense的补给状态
    go_attack_outpost,                //只推前哨站状态
};

enum sentry_event{
    none = 0,
    match_begin,                      //比赛开始
    turn_off_auto,                    //关自动模式
    turn_on_auto,                     //开自动模式
    target_detected,                  //目标出现

    target_disappear,                 //目标消失
    being_hit,                        //受击
    ammunition_capacity_reached_limit,//发弹量达到上限
    HP_low,                           //生命值低下
    logic_operate,                    //逻辑操作，作为debug判断，不会有实际用处

    HP_regeneration,                  //生命值恢复
    outpost_HP_low,                   //我方前哨站血量低下
    revive,                           //复活
    outpost_destroyed,                //我方前哨站被击毁
    radar_lock_target,                //雷达锁定目标

    operator_intervene,               //云台手干预
};

enum location{ //特定位置
    farthest_point = 0,             //最远点
    center_point = 1,               //中心点
    bottom_right_corner = 2,        //右下角
    top_right_corner = 3,           //右上角
    bottom_left_corner = 4,         //左下角
    top_left_corner = 5,            //左上角
    initial_point = 6,              //出生点
    radical_point = 7,              //激进点
    conservative_point = 8,         //保守点
    healing_point = 9,              //回血点

    /***************  以下地点RMUC用  *****************/
    enemy_gathering_point = 10,     //敌方汇进点
    enemy_base_entrance = 11,       //敌方基地口
    enemy_R1_entrance = 12,         //敌方R1坡口
    enemy_outpost_impact_point = 13,//敌方前哨站打击点

    our_base_patrol_zone = 14,      //我方基地巡逻区
    our_R2_patrol_zone = 15,        //我方R2巡逻区
    our_R3_patrol_zone = 16,        //我方R3巡逻区
    our_R4_patrol_zone = 17,        //我方R4巡逻区
    our_outpost_defence_zone = 18,  //我方前哨站保卫区
    our_bridge_tunnel_entrance = 19,//我方桥洞入口
    our_R1_entrance = 20,           //我方R1坡口
};

#pragma pack(1)
typedef struct {
    uint16_t ch0: 11;
    uint16_t ch1: 11;
    uint16_t ch2: 11;
    uint16_t ch3: 11;
    uint8_t s1: 2;
    uint8_t s2: 2;
    uint8_t is_lost: 1;
    uint8_t reverse_0: 7;
    uint8_t reverse_1: 8;
} rc_info_tran;
#pragma pack()

#pragma pack(1)
typedef struct {
    float yaw_angle;
    uint8_t is_flip_over: 1;
    uint8_t reverse_0: 7;
    uint8_t reverse_1: 8;
    uint8_t reverse_2: 8;
    uint8_t reverse_3: 8;
} chassis_info_tran;
#pragma pack()

#pragma pack(1)
typedef struct {            //都使用朴素机器人坐标系,前x,左y,上z
    float speed_x;
    float speed_y;
} speed_info;
#pragma pack()

typedef struct {            //都使用朴素机器人坐标系,前x,左y,上z
    float speed_x;
    float speed_y;
    float angle;            //单位deg 0-360
} radar_speed;


#pragma pack(1)
typedef struct {
    uint16_t current_HP;                //当前血量
    uint16_t shooter_barrel_cooling_value;    //机器人1号枪口每秒冷却值
    uint8_t  game_progress: 4;      //当前比赛阶段
    uint16_t stage_remain_time;     //当前阶段剩余时间，单位s
    /* bit 0-3 ：
      当血量变化类型为装甲伤害，代表装甲 ID ，
      其中数值为 0-4 号代表机器人的五个装甲片，
      其他血量变化类型，该变量数值为 0 */
    uint8_t be_hit: 1;              //是否受击
    uint8_t hurt_armor_id: 4;
    /*hurt_type
     *     bit 4-7 ：血量变化类型
     *     0x0 装甲伤害扣血
     *     0x1 模块掉线扣血
     *     0x2 超射速扣血
     *     0x3 超枪口热量扣血
     *     0x4 超底盘功率扣血
     *     0x5 装甲撞击扣血
     */
    uint8_t mains_power_shooter_output : 1;     //1 为有 24V 输出， 0 为无 24v 输出

    uint8_t is_occupy_patrol_zone: 1;      //是否占领巡逻区
    uint8_t is_occupy_healing_spot: 1;     //是否占领补血点

    uint8_t HP_deduction_reason: 4;
} judge_info_0;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t is_blue: 1;
    uint16_t shooter_barrel_heat_limit;    //机器人1号枪口热量上限
    uint16_t maximum_HP;                   //血量上限

    /*game_type
1 ：RoboMaster 机甲大师赛
2 ：RoboMaster 机甲大师单项赛
3 ：ICRA RoboMaster 人工智能挑战赛
4 ：RoboMaster 联盟赛 3V3
5 ：RoboMaster 联盟赛 1V1*/
    uint8_t  game_type: 4;
    uint16_t remaining_gold_coin;          //剩余金币
    uint64_t reverse: 11;
} judge_info_1;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint16_t projectile_allowance_17mm;    //允许发弹量
    uint8_t shooter_id;  //发射机构ID
    float bullet_speed;  //弹丸初速度
    uint64_t reverse: 8;
} judge_info_2;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint16_t shooter_17mm_1_barrel_heat; //第1个17mm发射机构的枪口热量
    uint16_t shooter_17mm_2_barrel_heat;
    uint32_t reverse;
} judge_info_3;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint16_t enemy_1_robot_HP;
    uint16_t enemy_2_robot_HP;
    uint16_t enemy_3_robot_HP;
    uint16_t enemy_4_robot_HP;
} judge_HP_info_0;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint16_t enemy_5_robot_HP;
    uint16_t enemy_7_robot_HP;
    uint16_t enemy_outpost_HP;
    uint16_t enemy_base_HP;
} judge_HP_info_1;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint16_t our_outpost_HP;
    uint16_t our_base_HP;
    uint64_t reserve: 32;
} judge_HP_info_2;
#pragma pack()

#pragma pack(1)
typedef struct {
    float chassis_yaw; //单位deg
    uint8_t is_target_detected: 1;
    uint8_t is_chassis_yaw_stop: 1;
    uint8_t is_spin: 1;
    uint8_t is_use_capacitor: 1;
    uint8_t high_speed_spin: 1;
    uint8_t high_speed_translation: 1;
    uint8_t slope_speed_translation: 1;
    uint64_t reserve: 25;
} chassis_yaw_info_tran;
#pragma pack()

typedef struct {
    float chassis_yaw; //单位deg
    uint8_t is_target_detected;
    uint8_t is_chassis_yaw_stop;
    uint8_t is_spin;
    uint8_t is_use_capacitor;
    uint8_t high_speed_spin;
    uint8_t high_speed_translation;
    uint8_t slope_speed_translation; //预备上坡标志位
} chassis_yaw_info;

#pragma pack(1)
typedef struct {
    float chassis_yaw_real;   //计算出来大yaw的值
    uint8_t is_confirm_revive: 1;                       //是否确认复活
    uint8_t is_exchange_immediate_revive: 1;            //是否兑换立即复活
    uint16_t exchange_ammo_amount: 11;                  //哨兵将要兑换的发弹量值，开局为0，修改此值后，哨兵在补血点即可兑换允许发弹量。
    uint8_t remote_exchange_ammo_request_count: 4;      //哨兵远程兑换发弹量的请求次数，开局为0，修改此值即可请求远程兑换发弹量。
    uint8_t remote_exchange_health_request_count: 4;    //哨兵远程兑换血量的请求次数，开局为0，修改此值即可请求远程兑换血量。
    uint32_t reserve: 11;                               //保留
} yaw_and_decision_info;
#pragma pack()

typedef struct {
    uint8_t is_confirm_revive;                      //是否确认复活
    uint8_t is_exchange_immediate_revive;           //是否兑换立即复活
    uint16_t exchange_ammo_amount;                  //哨兵将要兑换的发弹量值，开局为0，修改此值后，哨兵在补血点即可兑换允许发弹量。
    uint8_t remote_exchange_ammo_request_count;     //哨兵远程兑换发弹量的请求次数，开局为0，修改此值即可请求远程兑换发弹量。
    uint8_t remote_exchange_health_request_count;   //哨兵远程兑换血量的请求次数，开局为0，修改此值即可请求远程兑换血量。
} sentry_decision_info;


#pragma pack(1)
typedef struct {
    uint8_t enable;
    uint32_t power_charge;
    uint8_t ramp;       //飞坡标志位
    uint32_t reverse: 16;
} super_cap_tran;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t robot_number;
    uint8_t is_reliable;
    uint16_t x;
    uint16_t y;
    uint16_t reserve;
} enemy_coo_tran;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t robot_number;
    uint8_t is_reliable;
    float x;
    float y;
} enemy_coo;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t sentry_state;
    uint8_t sentry_destination;
    uint8_t sentry_event;
    uint8_t reserve_0;
    uint32_t reserve_1;
} sentry_to_robot_tran;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t sentry_state;
    uint8_t sentry_event;
    uint8_t sentry_destination;
} sentry_to_robot;
#pragma pack()

#pragma pack(1)
typedef struct {
    uint8_t cmd_keyboard;
    uint16_t position_x;
    uint16_t position_y;
    uint32_t reserve: 24;
} aerial_operator_data;
#pragma pack()


#ifdef __cplusplus
extern "C" {
#endif
//C
void communicate_task(void *argument);
void judge_unpack_task(void *argument);
void communicate_judge_task(void *argument);
void communicate_HP_task(void *argument);
void StulnteractiveTask(void *argument);
void communicate_robot_interaction_task(void *argument);
#ifdef __cplusplus
}
#endif
//C++

#endif //SENTRY_LEFT_GIMBAL_COMMUNICATE_TASK_H
